login_proxy_get_client_ostream(client->login_proxy);
const struct compression_handler *handler;
int ret = compression_lookup_handler(t_str_lcase(args[0]), &handler);
- if (ret <= 0) {
- /* IMAP backend normally checks this already. If we get here,
- there is a mismatch between what algorithms proxy and
- backend supports. */
+ /* Only DEFLATE is permitted. The IMAP backend restricts this already;
+ enforce it here too, since imap-login handles COMPRESS for proxied
+ connections and non-DEFLATE algorithms can be far more memory-heavy
+ to decompress. */
+ if (ret <= 0 || strcmp(handler->name, "deflate") != 0) {
o_stream_nsend_str(client_output, t_strdup_printf(
"%s NO %s compression mechanism\r\n", args[1],
- ret == 0 ? "Unsupported" : "Unknown"));
+ ret < 0 ? "Unknown" : "Unsupported"));
return 0;
}
return TRUE;
}
int ret = compression_lookup_handler(t_str_lcase(mechanism), &handler);
- if (ret <= 0) {
+ /* Only DEFLATE is advertised (RFC 4978) and accepted here. Other
+ algorithms (e.g. zstd) can require far more memory to decompress,
+ which especially matters now that imap-login can handle COMPRESS for
+ proxied connections and an attacker could open many of them. */
+ if (ret <= 0 || strcmp(handler->name, "deflate") != 0) {
const char * tagline =
t_strdup_printf("NO %s compression mechanism",
- ret == 0 ? "Unsupported" : "Unknown");
+ ret < 0 ? "Unknown" : "Unsupported");
client_send_tagline(cmd, tagline);
return TRUE;
}